
;---------------------------------------------
; flde v0.1 Fasmlab Disassembler Engine 32 bit
; ----------    BSD License   ----------------
; Copyright (c) 2009, Marc Rainer Kranz
; All rights reserved
;---------------------------------------------
;- SVN Repository at
;- http://code.google.com/p/flde/
;- 
;- code size  450
;- table size 284
;- copyright  112
;- total      864 byte

include "flde32.inc"

flde32_getlen:
	;IN EAX=pointer to istruction
	;RET ECX=len
	;RET EAX=pointer to istruction
	;RET EDX=info
	push ebp
	push ebx
	push edi
	push esi
	xor eax,eax
	mov ebp,table1
	mov esi,dword[esp+20]
	xor ebx,ebx
	push esi

.get_prefix:
	lodsb
	xor edx,edx
	xor ecx,ecx
	inc edx
	cmp al,0Fh
	jz	.try_0f
	inc ecx
	cmp al,66h
	jb .try_seg
	jz .is_pref
	inc ecx
	cmp al,67h
	jz .is_pref
	inc ecx
	cmp al,0F2h
	jz .is_pref
	inc ecx
	cmp al,0F3h
	jnz .no_prefix

.is_pref:
	shl dl,cl
	jmp	.set_pref

.try_seg:
	cmp al,26h
	jz	.is_seg
	inc ecx
	cmp al,2Eh
	jz	.is_seg
	inc ecx
	cmp al,36h
	jz	.is_seg
	inc ecx
	cmp al,3Eh
	jz	.is_seg
	inc ecx
	cmp al,64h
	jb	.no_prefix
	inc ecx
.is_seg:
	ror cl,3
	mov dl,cl

.set_pref:
	or ah,dl
	inc ebx
	jmp	.get_prefix

.try_0f:
	lodsb
	cmp al,24h
	jz	.sse5
	cmp al,3Ah
	jz	.sse3_4
	cmp al,7Bh
	jz	.sse3_4
	cmp al,38h
	jz	.sse3_4
	cmp al,7Ah
	jz	.sse3_4
	cmp al,25h
	jnz	.other_sse
	;--- check for tricky code -----
.sse5_25:
	inc ebx
.sse3_4:
.sse5:
	inc ebx
	lodsb

.other_sse:
	ror dl,1			; --> 80h
	inc ebx
	add ebp,edx
	mov cl,8
	test ah,PREF_66
	jnz	.instr_66
	test ah,PREF_F2
	jnz	.instr_F2
	test ah,PREF_F3
	jnz	.instr_F3

	or ah,PREF_0F
	jmp	.no_prefix

.instr_F2:
.instr_F3:
	sub cl,2
	add ebp,ecx
	sub cl,4

.instr_66:
	and ah,not PREF_0F
	add ebp,edx
	mov edi,ebp
	inc ebx
	inc ebx
	repnz scasb
	jnz	.get_modA
	lodsb
	inc ebx
	jmp	.get_modA

.no_prefix:
	;----------------------------------------
	;---- prefixing in ah
	;---- instr in al
	;---- count in ebx
	mov dh,ah		;<--- save prefixing
	inc ebx
	shl eax,8
	xor ecx,ecx
	mov al,ah
	
	shr al,1
	setnc cl
	add cl,cl
	xchg ebx,ebp
	add cl,cl
	xlatb
	shr al,cl
	xchg ebx,ebp
	mov dl,al
	and al,7
	and dl,8
	mov cl,al
	ror dl,3
	add bl,dl		;mod 1 byte added
	xor al,al
	add bl,cl
	test dl,dl
	jz .exit_lde

	;-----check operand size
	;-----get mod/sib------------------------
	mov cl,dh		;<--- save prefixing
	and dh,PREF_66
	jz	.get_mod
	sub ebx,2

.get_mod:
	lodsb
	test cl,PREF_0F		;skip weirdness because they have not 0F opcode as prefix
	jnz	.get_modA

	;--- consider weirdness of F6-F7/REG 000 test r/m8/v,imm8/imm
	;--- linear, not optimized --------------------------------------
	mov edx,eax
	xor ecx,ecx
	and al,0011'1000b
	test al,al
	setz cl
	sub ah,0F6h
	setz ch
	xor al,al
	and ch,cl
	dec ah
	setz cl
	setz al
	xor cl,ch
	add cl,al
	xor ch,ch
	add cl,al
	add cl,al
	add ebx,ecx
	mov eax,edx

	;--- consider weirdness of 9B/9B pure or 9B/DB-DF
	;--- linear, not optimized --------------------------------------
	xor ecx,ecx
	and dl,0D9H
	cmp ah,09Bh
	jnz	.get_modA
	inc ecx
	dec ebx
	inc ecx
	cmp dl,0D9h
	jnz	.exit_lde	;is single 9B
	or dl,al
	add ebx,ecx
	lodsb
	shr edx,cl
	jc	.exit_lde	;is +1 byte or is pure mod

.get_modA:
	mov ebp,mod32_table
	xor ecx,ecx
	xor edx,edx
	mov cl,al
	mov dh,al

	and cl,1100'0000b
	rol cl,4
	add ebp,ecx

	mov cl,al
	and cl,00000111b
	shr cl,1
	setnc dl
	mov al,byte[ebp+ecx]
	
	mov cl,dl
	add cl,cl
	add cl,cl

	shr al,cl
	and al,0Fh

	mov dl,al
	and dl,8
	and al,7		
	ror dl,3
	add bl,al		;size
	add bl,dl
	mov al,dh

.exit_lde:
	shl eax,8
	mov ecx,ebx
	mov edx,eax
	mov dl,bl

	pop eax
	pop esi
	pop edi
	pop ebx
	pop ebp
	ret 4

